home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / xcdplayer / cdrom_sun.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  13KB  |  688 lines

  1. /*
  2.  * Copyright (C) 1990 Regents of the University of California.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee,
  6.  * provided that the above copyright notice appear in all copies and that
  7.  * both that copyright notice and this permission notice appear in
  8.  * supporting documentation, and that the name of the University of
  9.  * California not be used in advertising or publicity pertaining to
  10.  * distribution of the software without specific, written prior
  11.  * permission.  the University of California makes no representations
  12.  * about the suitability of this software for any purpose.  It is provided
  13.  * "as is" without express or implied warranty.
  14.  */
  15.  
  16. static int c;
  17.  
  18. # if defined(sun)
  19. # include <stdio.h>
  20.  
  21. # include <sys/file.h>
  22. # include <sys/types.h>
  23. # include <sys/param.h>
  24. # include <sys/stat.h>
  25.  
  26. # include <sun/dkio.h>
  27.  
  28. # include <mntent.h>
  29. # include <string.h>
  30.  
  31. # include <sys/buf.h>
  32. # ifdef sun4c
  33. # include <scsi/targets/srdef.h>
  34. # else
  35. # include <sundev/srreg.h>
  36. # endif
  37.  
  38. # include <sys/time.h>
  39.  
  40. # include "debug.h"
  41. # include "cdrom_sun.h"
  42.  
  43. extern char    *device;
  44. # if defined(notdef)
  45. extern void    cdrom_print_toc();
  46. # endif /* defined(notdef) */
  47.  
  48. static char    cdrom[] =    "/dev/rsr0";
  49.  
  50. cdrom_info    cdi;
  51. char        info_filename[256];
  52. FILE        *disc_info = NULL;
  53.  
  54. static int    cdrom_fd = -1;
  55.  
  56. get_stored_info()
  57. {
  58.     int i,n;
  59.     char    line[100];
  60.     char    *title;
  61.  
  62.         if ( cdi.maxtrack == 0) {
  63.                 return(0);
  64.         }
  65.     for (i = 0, n = 0; i < cdi.maxtrack; i++)
  66.         n = n + ((i+1) * cdi.times[i]);
  67.     n = n / cdi.maxtrack;
  68.  
  69.         disc_title = NULL;
  70.     if (cdInfoDir != NULL)
  71.         sprintf(info_filename, "%s/cd.%d", cdInfoDir, n);
  72.     else
  73.         sprintf(info_filename, "cd.%d", n);
  74.  
  75.     if ((disc_info = fopen(info_filename, "r")) != NULL)
  76.     {
  77.         fgets(line, 100, disc_info);
  78.         title = strchr(line, ':');
  79.         if (title != NULL)
  80.         {
  81.             *(strchr(title, '\n')) = '\0';
  82.             disc_title = strdup(title + 1);
  83.         }
  84.         fgets(line, 100, disc_info);
  85.         sscanf(line, "Program: %s", program_str);
  86.     }
  87.         if (disc_title == NULL) {
  88.                 disc_title = NOTITLESTR;
  89.         }
  90. }
  91.  
  92. int
  93. cdrom_open() {
  94.     int    n;
  95.     extern void update_title();
  96.  
  97.     if (cdrom_fd != -1)
  98.         return(cdi.curtrack);
  99.  
  100.     if (device != NULL) {
  101.         if ((cdrom_fd = open(device, O_RDONLY)) == -1) {
  102.             debug-printf(stderr, "open: ");
  103.             return(-1);
  104.         }
  105.     } else {
  106.         if ((cdrom_fd = open(cdrom, O_RDONLY)) == -1) {
  107.             debug-printf(stderr, "open: ");
  108.             return(-1);
  109.         }
  110.     }
  111.  
  112.     if (cdrom_get_times() == -1) {
  113.         cdrom_close();
  114.         return(-1);
  115.     }
  116.  
  117.     if ((n = cdrom_get_curtrack()) == -1)
  118.         return(-1);
  119.  
  120.     get_stored_info();
  121.  
  122.     update_title();
  123.  
  124.     if (cdi.state & CDROM_STATE_PLAY)
  125.         cdi.curtrack = n;
  126.  
  127.     if (cdi.state & CDROM_STATE_SHUFFLE)
  128.         shuffle_setup();
  129.  
  130.     return(cdi.curtrack);
  131. }
  132.  
  133. void
  134. cdrom_close() {
  135.     if (cdrom_fd == -1)
  136.         return;
  137.  
  138.     if (cdi.times != NULL) {
  139.         free((char *) cdi.times);
  140.         free((char *) cdi.addrs);
  141.         cdi.times = NULL;
  142.         cdi.addrs = NULL;
  143.     }
  144.  
  145.     (void) close(cdrom_fd);
  146.     cdrom_fd = -1;
  147. }
  148.  
  149.  
  150. int
  151. cdrom_start() {
  152.     if (cdrom_fd == -1)
  153.         return(-1);
  154.  
  155.     if (ioctl(cdrom_fd, CDROMSTART) == -1) {
  156.         perror("ioctl(cdromstart)");
  157.         return(-1);
  158.     }
  159.  
  160.     return(0);
  161. }
  162.  
  163. int
  164. cdrom_stop() {
  165.     if (cdrom_fd == -1)
  166.         return(-1);
  167.  
  168.     if (ioctl(cdrom_fd, CDROMSTOP) == -1) {
  169.         perror("ioctl(cdromstop)");
  170.         return(-1);
  171.     }
  172.  
  173.     return(0);
  174. }
  175.  
  176. int
  177. cdrom_eject() {
  178.     if (cdrom_fd == -1)
  179.         return(-1);
  180.  
  181.     if (ioctl(cdrom_fd, CDROMEJECT) == -1) {
  182.         perror("ioctl(cdromeject)");
  183.         return(-1);
  184.     }
  185.  
  186.     return(0);
  187. }
  188.  
  189. int
  190. cdrom_pause() {
  191.     if (cdrom_fd == -1)
  192.         return(-1);
  193.  
  194.     if (ioctl(cdrom_fd, CDROMPAUSE) == -1) {
  195.         perror("ioctl(cdrompause)");
  196.         return(-1);
  197.     }
  198.  
  199.     return(0);
  200. }
  201.  
  202. int
  203. cdrom_resume() {
  204.     if (cdrom_fd == -1)
  205.         return(-1);
  206.  
  207.     if (ioctl(cdrom_fd, CDROMRESUME) == -1) {
  208.         perror("ioctl(cdromresume)");
  209.         return(-1);
  210.     }
  211.  
  212.     return(0);
  213. }
  214.  
  215. int
  216. cdrom_volume(left_vol, right_vol)
  217.     int            left_vol;
  218.     int            right_vol;
  219. {
  220.     struct cdrom_volctrl    vol;
  221.  
  222.     if (cdrom_fd == -1)
  223.         return(-1);
  224.  
  225.     vol.channel0 = left_vol;
  226.     vol.channel1 = right_vol;
  227.  
  228.     if (ioctl(cdrom_fd, CDROMVOLCTRL, &vol) == -1) {
  229.         perror("ioctl(cdromvolctrl)");
  230.         return(-1);
  231.     }
  232.  
  233.     return(0);
  234. }
  235.  
  236. int
  237. cdrom_get_times() {
  238.     struct cdrom_tochdr    tochdr;
  239.     extern unsigned short    *ushort_malloc();
  240.     extern struct msf    *msf_malloc();
  241.     unsigned long        trk, trk_total, otime;
  242.     struct msf        msf;
  243.  
  244.     if (cdrom_read_tochdr(&tochdr) == -1)
  245.         return(-1);
  246.  
  247.     cdi.mintrack = tochdr.cdth_trk0;
  248.     cdi.maxtrack = tochdr.cdth_trk1;
  249.  
  250.     if (cdi.times != NULL)
  251.     {
  252.         free((char *) cdi.times);
  253.         free((char *) cdi.addrs);
  254.         cdi.times = NULL;
  255.         cdi.addrs = NULL;
  256.     }
  257.  
  258.     cdi.times = ushort_malloc(cdi.maxtrack - cdi.mintrack + 1);
  259.     cdi.addrs = msf_malloc(cdi.maxtrack - cdi.mintrack + 2);
  260.  
  261.     otime = 0;
  262.  
  263.     for (trk = cdi.mintrack; trk <= cdi.maxtrack; trk++) {
  264.         if (cdrom_get_msf(trk, &msf, &trk_total) == -1)
  265.             return(-1);
  266.  
  267.         /* record start address for each track (track 1 starts at 0)*/
  268.         cdi.addrs[trk - cdi.mintrack] = msf;
  269.  
  270.         trk_total -= otime;
  271.  
  272.         /* use start time of next track as length of previous */
  273.         if (otime != 0) 
  274.         {
  275.             cdi.times[trk - cdi.mintrack - 1] = trk_total;
  276.         }
  277.  
  278.         otime += trk_total;
  279.  
  280.     }
  281.  
  282.     /* find start of  leadout to get length of last track */
  283.     if (cdrom_get_msf(CDROM_LEADOUT, &msf, &trk_total) == -1)
  284.         return(-1);
  285.  
  286.     /* recode leadout start address */
  287.     cdi.addrs[trk - cdi.mintrack] = msf;
  288.     trk_total -= otime;
  289.     otime += trk_total;
  290.  
  291.     cdi.times[trk - cdi.mintrack - 1] = trk_total;
  292.  
  293.     return(0);
  294. }
  295.  
  296. # if defined(notdef)
  297. static void
  298. cdrom_print_toc() {
  299.     unsigned long        trk, trk_total;
  300.  
  301.     for (trk = cdi.mintrack; trk <= cdi.maxtrack; trk++) {
  302.         trk_total = cdi.times[trk - cdi.mintrack];
  303.         debug_printf(1, "%02u:%02u\n", trk_total/60, trk_total%60);
  304.     }
  305. }
  306. # endif /* defined(notdef) */
  307.  
  308. int
  309. cdrom_get_curtrack() {
  310.     struct cdrom_subchnl    subchnl;
  311.  
  312.     if (cdrom_fd == -1)
  313.         return(-1);
  314.  
  315.     if (ioctl(cdrom_fd, CDROMSUBCHNL, (char *) &subchnl) == -1) {
  316.         fprintf(stderr, "ioctl(cdromsubchnl): ");
  317.         perror(cdrom);
  318.         return(-1);
  319.     }
  320.  
  321.     switch (subchnl.cdsc_audiostatus) {
  322.         case CDROM_AUDIO_INVALID:
  323.         return(-1);
  324.  
  325.         /* playing track subchnl.cdsc_trk */
  326.         case CDROM_AUDIO_PLAY:
  327.         return((int) subchnl.cdsc_trk);
  328.  
  329.         /* paused on track subchnl.cdsc_trk */
  330.         case CDROM_AUDIO_PAUSED:
  331.         return((int) subchnl.cdsc_trk);
  332.  
  333.         /* punt */
  334.         case CDROM_AUDIO_COMPLETED:
  335.         return(0);
  336.  
  337.         case CDROM_AUDIO_ERROR:
  338.         return(-1);
  339.  
  340.         /* punt */
  341.         case CDROM_AUDIO_NO_STATUS:
  342.         debug_printf(1, "cdrom_get_curtrack: no status\n");
  343.         return(0);
  344.     }
  345.  
  346.     /* bad value in cdsc_audiostatus */
  347.     return(-1);
  348. }
  349.  
  350. int
  351. cdrom_get_msf(track, msf, length)
  352.     unsigned long        track;
  353.     struct msf        *msf;
  354.     unsigned long        *length;
  355. {
  356.     struct cdrom_tocentry    tocentry;
  357.  
  358.     if (cdrom_read_tocentry(track, &tocentry) == -1)
  359.         return(-1);
  360.  
  361.     msf->minute = tocentry.cdte_addr.msf.minute;
  362.     msf->second = tocentry.cdte_addr.msf.second;
  363.     msf->frame = tocentry.cdte_addr.msf.frame;
  364.  
  365.     *length = ((int) tocentry.cdte_addr.msf.minute * 60) +
  366.         (int) tocentry.cdte_addr.msf.second;
  367.  
  368.     return(0);
  369. }
  370.  
  371. int
  372. cdrom_get_curmsf(msf)
  373.     struct msf *msf;
  374. {
  375.     struct cdrom_subchnl    subchnl;
  376.  
  377.     if (cdrom_fd == -1)
  378.         return(-1);
  379.  
  380.     subchnl.cdsc_format = CDROM_MSF;
  381.  
  382.     if (ioctl(cdrom_fd, CDROMSUBCHNL, (char *) &subchnl) == -1) {
  383.         perror("ioctl(cdromsubchnl)");
  384.         return(-1);
  385.     }
  386.  
  387.     msf->minute = subchnl.cdsc_absaddr.msf.minute;
  388.     msf->second = subchnl.cdsc_absaddr.msf.second;
  389.     msf->frame = subchnl.cdsc_absaddr.msf.frame;
  390.  
  391.     return (0);
  392.  
  393. }
  394.  
  395. int
  396. cdrom_play_track(start_track, end_track)
  397.     unsigned char        start_track;
  398.     unsigned char        end_track;
  399. {
  400.     struct    cdrom_ti    ti;
  401.  
  402.     if (cdrom_fd == -1)
  403.         return(-1);
  404.  
  405.     ti.cdti_trk0 = start_track;
  406.     ti.cdti_ind0 = 1;
  407.     ti.cdti_trk1 = end_track;
  408.     ti.cdti_ind1 = 1;
  409.  
  410.     if (ioctl(cdrom_fd, CDROMPLAYTRKIND, &ti) == -1) {
  411.         perror("ioctl(cdromplaytrkind)");
  412.         return(-1);
  413.     }
  414.  
  415.     return(0);
  416. }
  417.  
  418. int
  419. cdrom_play_msf(start_msf, end_msf)
  420.     struct msf    *start_msf;
  421.     struct msf    *end_msf;
  422. {
  423.     struct    cdrom_msf    play_addr;
  424.  
  425.     if (cdrom_fd == -1)
  426.         return(-1);
  427.  
  428.     play_addr.cdmsf_min0 = start_msf->minute;
  429.     play_addr.cdmsf_sec0 = start_msf->second;
  430.     play_addr.cdmsf_frame0 = start_msf->frame;
  431.     play_addr.cdmsf_min1 = end_msf->minute;
  432.     play_addr.cdmsf_sec1 = end_msf->second;
  433.     play_addr.cdmsf_frame1 = end_msf->frame;
  434.  
  435.     if (ioctl(cdrom_fd, CDROMPLAYMSF, &play_addr) == -1) {
  436.         perror("ioctl(cdromplaymsf)");
  437.         return(-1);
  438.     }
  439.  
  440.     return(0);
  441. }
  442. int
  443. cdrom_read_tocentry(track, tocentry)
  444.     unsigned int        track;
  445.     struct cdrom_tocentry    *tocentry;
  446. {
  447.     if (cdrom_fd == -1)
  448.         return(-1);
  449.  
  450.     tocentry->cdte_track = track;
  451.     tocentry->cdte_format = CDROM_MSF;
  452.  
  453.     if (ioctl(cdrom_fd, CDROMREADTOCENTRY, (char *) tocentry) == -1) {
  454.         perror("ioctl(cdromreadtocentry)");
  455.         return(-1);
  456.     }
  457.  
  458.     return(0);
  459. }
  460.  
  461. int
  462. cdrom_read_tochdr(tochdr)
  463.     struct cdrom_tochdr    *tochdr;
  464. {
  465.     if (cdrom_fd == -1)
  466.         return(-1);
  467.  
  468.     if (ioctl(cdrom_fd, CDROMREADTOCHDR, (char *) tochdr) == -1) {
  469.         debug-printf(stderr,"ioctl(cdromreadtochdr): ");
  470.         /* perror("ioctl(cdromreadtochdr)"); */
  471.         return(-1);
  472.     }
  473.  
  474.     return(0);
  475. }
  476.  
  477. int
  478. cdrom_status() {
  479.     struct cdrom_subchnl    subchnl;
  480.  
  481.     if (cdrom_fd == -1)
  482.         return(-1);
  483.  
  484.     if (ioctl(cdrom_fd, CDROMSUBCHNL, (char *) &subchnl) == -1) {
  485.         fprintf(stderr, "ioctl(cdromsubchnl): ");
  486.         perror(cdrom);
  487.         exit(1);
  488.     }
  489.  
  490.     switch (subchnl.cdsc_audiostatus) {
  491.         case CDROM_AUDIO_INVALID:
  492.         return(CDROM_INVALID);
  493.  
  494.         case CDROM_AUDIO_PLAY:
  495.         return(CDROM_PLAYING);
  496.  
  497.         case CDROM_AUDIO_PAUSED:
  498.         return(CDROM_PAUSED);
  499.  
  500.         case CDROM_AUDIO_COMPLETED:
  501.         return(CDROM_COMPLETED);
  502.  
  503.         case CDROM_AUDIO_ERROR:
  504.         return(CDROM_ERROR);
  505.  
  506.         case CDROM_AUDIO_NO_STATUS:
  507.         return(CDROM_NO_STATUS);
  508.     }
  509.  
  510.     return(-1);
  511. }
  512.  
  513. # if defined(notused)
  514. int
  515. cdrom_playing(track)
  516.     int            *track;
  517. {
  518.     struct cdrom_subchnl    sc;
  519.  
  520.     if (cdrom_fd == -1)
  521.         return(-1);
  522.  
  523.     sc.cdsc_format = CDROM_MSF;
  524.     if (ioctl(cdrom_fd, CDROMSUBCHNL, &sc) == -1) {
  525.         perror("ioctl(cdromsubchnl)");
  526.         return(-1);
  527.     }
  528.  
  529.     *track = sc.cdsc_trk;
  530.  
  531.     if (sc.cdsc_audiostatus == CDROM_AUDIO_PLAY)
  532.         return(1);
  533.  
  534.     return(0);
  535. }
  536. # endif /* defined(notused) */
  537.  
  538. # if defined(notused)
  539. int
  540. cdrom_paused(track)
  541.     int            *track;
  542. {
  543.     struct cdrom_subchnl    sc;
  544.  
  545.     if (cdrom_fd == -1)
  546.         return(-1);
  547.  
  548.     sc.cdsc_format = CDROM_MSF;
  549.     if (ioctl(cdrom_fd, CDROMSUBCHNL, &sc) == -1) {
  550.         perror("ioctl(cdromsubchnl)");
  551.         return(-1);
  552.     }
  553.  
  554.     *track = sc.cdsc_trk;
  555.  
  556.     if (sc.cdsc_audiostatus == CDROM_AUDIO_PAUSED)
  557.         return(1);
  558.  
  559.     return(0);
  560. }
  561. # endif /* defined(notused) */
  562.  
  563. # if defined(notused)
  564. int
  565. mounted(name)
  566.     char        *name;
  567. {
  568.     char        buf[MAXPATHLEN], *cp;
  569.     struct stat    st;
  570.     dev_t        bdevno;
  571.     FILE        *fp;
  572.     struct mntent    *mnt;
  573.  
  574.     /*
  575.      * Get the block device corresponding to the raw device opened,
  576.      * and find its device number.
  577.      */
  578.     if (stat(name, &st) != 0) {
  579.         (void) fprintf(stderr, "stat: ");
  580.         perror(name);
  581.         return(UNMOUNTED);
  582.     }
  583.  
  584.     /*
  585.      * If this is a raw device, we have to build the block device name.
  586.      */
  587.     if ((st.st_mode & S_IFMT) == S_IFCHR) {
  588.         if ((cp = strchr(name, 'r')) != NULL)
  589.             cp++;
  590.  
  591.         (void) sprintf(buf, "/dev/%s", cp);
  592.         if (stat(buf, &st) != 0) {
  593.             (void) fprintf(stderr, "stat: ");
  594.             perror(buf);
  595.             return(UNMOUNTED);
  596.         }
  597.     }
  598.  
  599.     if ((st.st_mode & S_IFMT) != S_IFBLK)
  600.         return(UNMOUNTED);
  601.  
  602.     bdevno = st.st_rdev & (dev_t)(~0x07);    /* Mask out partition. */
  603.  
  604.     /*
  605.      * Now go through the mtab, looking at all hsfs filesystems.
  606.      * Compare the device mounted with our bdevno.
  607.      */
  608.     if ((fp = setmntent(MOUNTED, "r")) == NULL) {
  609.         (void) fprintf(stderr, "couldn't open %s\n", MOUNTED);
  610.         return(UNMOUNTED);
  611.     }
  612.  
  613.     while ((mnt = getmntent(fp)) != NULL) {
  614.         /* avoid obvious excess stat(2)'s */
  615.         if (strcmp(mnt->mnt_type, "hsfs") != 0)
  616.             continue;
  617.  
  618.         if (stat(mnt->mnt_fsname, &st) != 0)
  619.             continue;
  620.  
  621.         if (((st.st_mode & S_IFMT) == S_IFBLK) &&
  622.             ((st.st_rdev & (dev_t)(~0x07)) == bdevno)) {
  623.             (void) endmntent(fp);
  624.             return(STILL_MOUNTED);
  625.         }
  626.     }
  627.  
  628.     (void) endmntent(fp);
  629.  
  630.     return(UNMOUNTED);
  631. }
  632. # endif /* defined(notused) */
  633.  
  634. unsigned short *
  635. ushort_malloc(n)
  636.     int        n;
  637. {
  638.     extern char    *calloc();
  639.     unsigned short    *ptr;
  640.  
  641.     ptr = (unsigned short *) calloc(n, sizeof(unsigned short));
  642.     if (ptr == NULL) {
  643.         perror("calloc");
  644.         exit(1);
  645.     }
  646.  
  647.     return(ptr);
  648. }
  649.  
  650. struct msf *
  651. msf_malloc(n)
  652.     int        n;
  653. {
  654.     extern char    *calloc();
  655.     struct msf    *ptr;
  656.  
  657.     ptr = (struct msf *) calloc(n, sizeof(struct msf));
  658.     if (ptr == NULL) {
  659.         perror("calloc");
  660.         exit(1);
  661.     }
  662.  
  663.     return(ptr);
  664. }
  665.  
  666. int
  667. cdrom_disp_cdi() {
  668.     int trk;
  669.  
  670.     fprintf(stderr,"CDI structure:\n");
  671.     fprintf(stderr,"\tcurtrack: %d\n",cdi.curtrack);
  672.     fprintf(stderr,"\tmin: %d  max: %d  total: %d\n",
  673.         cdi.mintrack, cdi.maxtrack, cdi.ntracks);
  674.     fprintf(stderr,"\tdur: %d  state: %2x\n",cdi.duration, cdi.state);
  675.     fprintf(stderr,"\tcurrand: %d  lastprog: %d\n",
  676.         cdi.currand, cdi.lastprog);
  677.     fprintf(stderr,"\n\tTracklist:\n");
  678.     if (cdi.maxtrack != cdi.mintrack) {
  679.         for (trk=cdi.mintrack; trk<=cdi.maxtrack; trk++) {
  680.             fprintf(stderr,"\t%3d: %d %02d:%02d %d\n",trk,cdi.times[trk],
  681.                 cdi.addrs[trk].minute,cdi.addrs[trk].second,
  682.                 cdi.addrs[trk].frame);
  683.         }
  684.     }
  685. }
  686.  
  687. # endif /* defined(sun) */
  688.